<template>
  <div class="flex-grow-0 w-full h-full overflow-y-scroll bg-white">
    <div class="w-2/3 mx-auto my-10 space-y-4 text-gray-500 cursor-pointer select-none">
      <div class="text-sm">{{ t('detail.nav_title') }} / {{ courseHook.course?.title }}</div>

      <div
        class="flex flex-col p-6 space-y-4 bg-white border rounded-md shadow-md bg-gradient-to-br from-mainColor to-secondaryColor"
      >
        <div class="flex items-center space-x-5">
          <div class="text-2xl text-fonts-100">
            {{ courseHook.course?.title }}
          </div>
        </div>
        <p class="text-fonts-100">
          {{ courseHook.course?.description }}
        </p>
      </div>
      <div class="p-6 bg-white border rounded-md shadow-md">
        <p class="text-2xl font-bold">{{ t('detail.introduction_title') }}</p>

        <a-divider></a-divider>

        <div class="p-6 bg-gray-50">
          <a-row>
            <a-col v-for="item in courseHook.documents" :span="12">
              <a-row :gutter="[12, 12]">
                <a-col>
                  <i class="w-5 h-5 block text-green-500 i-ic:sharp-check"></i>
                </a-col>
                <a-col>
                  <span class="font-bold">{{ item.title }}</span>
                </a-col>
              </a-row>
            </a-col>
          </a-row>
        </div>
      </div>
      <div class="p-6 bg-white border rounded-md shadow-md">
        <div class="flex justify-between">
          <p class="text-xl font-bold">{{ t('detail.content_title') }}</p>
          <span>
            {{
              t('detail.content_sub_title', {
                count: courseHook.documents?.length
              })
            }}
          </span>
        </div>

        <a-divider></a-divider>

        <a-row :gutter="[16, 16]">
          <a-col v-for="item in courseHook.documents" :span="24" @click="handleClick(item as Document)">
            <a-row :gutter="[16, 16]" align="middle" class="bg-gray-50 py-4 px-2 rounded-md hover:bg-gray-100">
              <a-col>
                <i class="h-8 w-8 block i-ph:terminal-fill"></i>
              </a-col>
              <a-col>
                <span class="text-lg">{{ item.title }}</span>
              </a-col>
            </a-row>
          </a-col>
        </a-row>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { Document, MyInfoDocument, MyInfoQuery } from '@/generated/graphql'
import { Ec2Services } from '@/hooks/services/ec2Services'
import { OpenstackServices } from '@/hooks/services/openstackServices'
import { BindSession, OpenstackSession } from '@/hooks/services/openstackSession'
import { useLoading } from '@/plugins/loading'
import { urqlOptions } from '@/plugins/urql'
import { Route } from '@/router'
import { useDockerApiPath } from '@/stores/dockerApi'
import { useCourseSessionStore } from '@/stores/useCourseStore'
import { Client } from '@urql/vue'
import { message, Modal } from 'ant-design-vue'
import { has } from 'lodash-es'
import { createVNode, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'

const router = useRouter()

const { t } = useI18n()

// 课程 hook
const courseHook = useCourseSessionStore()

onMounted(() => {
  // 只有一门章节的情况直接进入
  if (courseHook.documents && courseHook.documents.length == 1) {
    handleClick(courseHook.documents[0])
  }
})

// 创建一个graphql 客户端用于能够通过await 请求数据
const urqlClient = new Client(urqlOptions)
const dockerAPIStore = useDockerApiPath()

// 本地openstack的一些前置操作
const openstack_handle = async (item: Document) => {
  courseHook.setType('PRIVATE')

  const openstack = new OpenstackServices(urqlClient)
  const openstackSession = new OpenstackSession(openstack, router)

  let documentBackendsTag //当前课程是否需要gpu
console.log(item);

  //通过数据库backends 里面的tag 判断是需要cpu 还是gpu的实例
  documentBackendsTag = item.extends.PRIVATE.backends[0].tag ?? 'test-nginx-nfs'

  //获取当前用户session
  const myInfo = await urqlClient.query<MyInfoQuery>(MyInfoDocument, {}).toPromise()

  /**设置 本地openstack 绑定session需要的参数 */
  let bindSession: BindSession

  bindSession = {
    tags: documentBackendsTag.split(','),
    backends: item.extends.PRIVATE.backends[0],
    createSessionData: {
      courseId: courseHook.course?.id ?? '',
      documentId: courseHook.document?.id ?? ''
    }
  }

  /**判断当前用户是否存在session */
  if (myInfo.data?.me?.session) {
    const openstackInstance = myInfo.data?.me?.session?.instances[0]
    const instanceTags = openstackInstance?.private?.tags //获取实例的tag 类型

    //提取实例的网络IP 地址
    const openstackPath = openstackInstance.private?.addresses?.['network-public']?.[0]?.addr ?? 'docker-none'

    //判断实例类型是不是当前课程需要的类型 (vgpu/cpu)，本地这里只用判断处理器类型即可
    const tagsCompare = openstackSession.CompareTags(instanceTags, documentBackendsTag.split(','))

    if (tagsCompare) {
      //当前需要启动的环境和已有的环境相同
      dockerAPIStore.setIP(openstackPath)
      router.push({ name: Route.WAITING })
      return
    } else {
      openstackSession.ShowChangeModal('是否切换环境?', myInfo.data?.me?.session?.id as string, bindSession, () => {
        router.push({ name: Route.WAITING })
      })
      return
    }
  }

  //这里就判断gpu/cpu 和 windows/linux，不判断课程，windows镜像是同一个，linux 是docker环境里面判断课程然后重启docker 镜像
  const routerPath = await openstackSession.BindSession(bindSession)

  dockerAPIStore.setIP(routerPath.routerPath)
  dockerAPIStore.setWindows(routerPath.type !== 'linux')

  //设置docker 的api
  router.replace({ name: Route.WAITING })
}

const ec2Service = new Ec2Services(urqlClient)
// 弹窗确认是否需要删除会话
const showConfirm = (courseName: string, instanceId: string, item: Document) => {
  Modal.confirm({
    title: '当前已经存在以下课程的会话信息是否需要删除已存在的会话?',
    content: createVNode('div', { style: 'color:red;' }, courseName),
    onOk: async () => {
      await ec2Service.deleteOneSession(instanceId)
      await handleClick(item)
    },
    onCancel() {
      router.replace({ name: Route.COMPETITION })
    },
    class: ''
  })
}

// 弹窗确认需要进入的平台
const choosePlatform = (item: Document) => {
  Modal.confirm({
    title: '监测到存在多个环境配置，请选择需要进入的环境?',
    okText: '云环境',
    cancelText: '本地环境',
    onOk: async () => {
      await cloudPlatform(item)
    },
    onCancel() {
      openstack_handle(item)
    },
    class: ''
  })
}

// 进入云环境
const cloudPlatform = async (document: Document) => {
  courseHook.setType('PUBLIC')
  const publicExtends = document.extends?.PUBLIC
  const backend = publicExtends.backends[0]

  const courseId = courseHook.course?.id as string
  const documentId = document.id as string
  const duration = document.extends?.duration?.stop ?? 43200
  const termiate = document.extends?.duration?.termiate ?? 1036800
  const environment = publicExtends?.environment ?? []
  const sst = ec2Service.getSST(duration, termiate)

  try {
    const sessionReq = await ec2Service.createSession({
      courseId,
      documentId,
      duration,
      termiate,
      environment: { environment },
      backends: [
        {
          platformType: 'PUBLIC',
          data: {
            ...backend,
            TagSpecifications: [
              {
                ResourceType: 'instance',
                Tags: sst
              }
            ]
          }
        }
      ]
    })

    console.log(sessionReq)

    if (!sessionReq.error) {
      await router.replace({ name: Route.CHAPTER })
      router.go(0)
    } else {
      message.error(sessionReq.error?.message ?? '创建会话失败', 2, async () => {
        await router.replace({ name: Route.COMPETITION })
        router.go(0)
      })

      return
    }
  } catch (e) {
    message.error(e?.message ?? '创建会话失败')
    await router.replace({ name: Route.COMPETITION })
    return
  }
}

/**
 * 点击章节之后进入章节的逻辑
 */
const handleClick = async (item: Document) => {
  const { destroy: unMountLoading, update: loadingUpdate } = useLoading({
    content: t('waiting.container')
  })

  // 设置当前用户点击的章节信息
  courseHook.setDocument(item)

  const me = await urqlClient.query<MyInfoQuery>(MyInfoDocument).toPromise()
  const mySession = me.data?.me?.session
  const curDocumentExtends = courseHook.document?.extends

  // 判断是否已经存在session
  if (mySession) {
    if (mySession.course.id !== courseHook.course?.id) {
      // 存在session 让用户决定是否删除之前的session
      const courseName = mySession.course.title

      unMountLoading()
      showConfirm(courseName, mySession.id, item)
    } else {
      unMountLoading()
      await router.replace({ name: Route.CHAPTER })
      return
    }
  } else {
    // 不存在session
    if (courseHook.isMix) {
      // 混合情况，用户选择使用哪一个平台
      choosePlatform(item)
    } else {
      if (has(curDocumentExtends, 'PUBLIC')) {
        // 云环境平台
        courseHook.setType('PUBLIC')
        await cloudPlatform(item)
      } else {
        // 本地混合云平台
        courseHook.setType('PRIVATE')
        await openstack_handle(item)
      }
    }
  }
}
</script>
